package class_load.reflect;

import class_load.Student;
import org.junit.Before;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @program: baseModule
 * @description:
 * @author: zhanghz001
 * @create: 2020-10-28 13:05
 **/
public class Demo1 {
    Class<Student> clazz = null;
    Student student = null;

    @Before
    public void before() throws Exception {
        System.out.println("创建类对象");
        clazz = Student.class;
        student = new Student(10, "name10");
    }

    @Test
    public void test4() throws Exception {
        Method[] methods = clazz.getMethods();
        System.out.println("===========所有公共方法,包括父类=============");
        for (int i = 0; i < methods.length; i++) {
            System.out.println(methods[i]);
        }
        System.out.println("============所有本类方法,不仅仅是公共的方法============");
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (int i = 0; i < declaredMethods.length; i++) {
            System.out.println(declaredMethods[i]);
        }
        System.out.println("=========获取非公共方法执行===============");
        Method setName = clazz.getDeclaredMethod("setName1", String.class);
        setName.setAccessible(true);
        setName.invoke(student, "这是一个寂寞的天");
        System.out.println(student);
        System.out.println("============获取公共方法,并且执行============");
        Method method = clazz.getMethod("getName");
        Object invoke = method.invoke(student);
        System.out.println(invoke);
        System.out.println("========================");
        System.out.println("========================");
    }

    @Test
    public void test1() throws Exception {
        //只有在public修饰的空参构造才能搞
        Class<Student> clazz = Student.class;

        Student student = clazz.newInstance();
        System.out.println(student);
    }

    @Test
    public void testAllFields() throws Exception {
        //
        System.out.println("++========获取到所有public fields=========");
        Field[] fields = clazz.getFields();
        for (int i = 0; i < fields.length; i++) {
            System.out.println(fields[i]);
        }
        System.out.println("++========获取到所有private fields=========");
        Field[] declaredFields = clazz.getDeclaredFields();
        for (int i = 0; i < declaredFields.length; i++) {
            System.out.println(declaredFields[i]);
        }
    }

    @Test
    public void testField() throws Exception {
        System.out.println("=========publicV===========");
        Field publicV = clazz.getField("publicV");
        publicV.setInt(student, 111);
        System.out.println(student.publicV);
        System.out.println("=========voidV===========");
        Field voidV = clazz.getDeclaredField("voidV");
        voidV.setAccessible(true);
        voidV.setInt(student, 111);

        System.out.println("获取");
        int anInt = voidV.getInt(student);
        System.out.println(anInt);
    }

    @Test
    public void testConstructor() throws IOException, NoSuchMethodException, IllegalAccessException,
            InvocationTargetException, InstantiationException {
        //
        Class<Student> clazz = Student.class;

        //获取所有构造方法
        Constructor<?>[] constructors = clazz.getConstructors();
        for (int i = 0; i < constructors.length; i++) {
            System.out.println(constructors[i]);
        }
        System.out.println("==============");
        Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
        for (int i = 0; i < declaredConstructors.length; i++) {
            System.out.println(declaredConstructors[i]);
        }
        System.out.println("============public constructor===========");
        //
        //构造方法获取到对象
        Constructor<Student> constructor = clazz.getConstructor(int.class, String.class);
        Student name1 = constructor.newInstance(1, "name1");
        System.out.println(name1);

        System.out.println("======private constructor==============");
        //
        Constructor<Student> declaredConstructor = clazz.getDeclaredConstructor(int.class);
        //不是public的都要取消检查,再创建对象
        declaredConstructor.setAccessible(true);
        Student student = declaredConstructor.newInstance(10);
        System.out.println(student);
        //
        System.out.println("==========无修饰符 constructor=========");
        Constructor<Student> declaredConstructor1 = clazz.getDeclaredConstructor();
        declaredConstructor1.setAccessible(true);
        Student student1 = declaredConstructor1.newInstance();
        System.out.println(student1);
        //
        //
    }

    @Test
    public void testRefrectGetClass() throws IOException, NoSuchMethodException, IllegalAccessException,
            InvocationTargetException,
            InstantiationException, ClassNotFoundException {
        Class<Student> studentClass = Student.class;
        System.out.println(studentClass);
        Student student = new Student(20, "name20");
        Class<? extends Student> studentClass1 = student.getClass();
        System.out.println(studentClass1);
        //全类名
        Class<?> name = Class.forName("generate.Student");
        System.out.println(name);
        System.out.println(name == studentClass && studentClass == studentClass1);
    }

}
